using System;
using System.Collections.Generic;
using System.Text;
using Barrage.Global;
using SlimDX;
using SlimDX.Direct3D9;

namespace Barrage
{
    /// <summary>
    /// Usually represents a renderable Item in the 3D Environment
    /// </summary>
    public class Item:Element
    {
        /// <summary>
        /// List of meshes associated to this Item
        /// </summary>
        protected List<Mesh> meshes = new List<Mesh>(1);
        /// <summary>
        /// List of meshes associated to this Item
        /// </summary>
        public List <Mesh> Meshes { get { return meshes; } }

        /// <summary>
        /// List of audios associated to this Item
        /// </summary>
        protected List<Audio> audios = new List<Audio>(1);
        /// <summary>
        /// List of audios associated to this Item
        /// </summary>
        public List<Audio> Audios { get { return audios; } }

        /// <summary>
        /// Timer associated to this item (defaults to DefaultTimer)
        /// </summary>
        protected Timer timer = null;
        /// <summary>
        /// Timer associated to this item (defaults to DefaultTimer)
        /// </summary>
        public Timer Timer { get { return timer; } }

        /// <summary>
        /// Base constructor. No meshes are added
        /// </summary>
        public Item()
        {
            timer = Timer.DefaultTimer;
        }

        /// <summary>
        /// Base constructor with a default Mesh
        /// </summary>
        /// <param name="m">Mesh that the item will hold</param>
        public Item(Mesh m):this()
        {
            meshes.Add(m);
        }

        /// <summary>
        /// Adds a mesh to the item mesh list
        /// </summary>
        /// <param name="m">Mesh to be added</param>
        public void addMesh(Mesh m)
        {
            meshes.Add(m);
        }

        /// <summary>
        /// Adds an audio to the item audio list
        /// </summary>
        /// <param name="a">Audio to be added</param>
        public void addAudio(Audio a)
        {
            audios.Add(a);
        }

        /// <summary>
        /// Utility property: First mesh of the mesh list
        /// </summary>
        public Mesh Mesh { get { if (meshes.Count > 0) return meshes[0]; return null; } }
        /// <summary>
        /// Utility property: First audio of the audio list
        /// </summary>
        public Audio Audio { get { if (audios.Count > 0) return audios[0]; return null; } }

        /// <summary>
        /// \internal Renders the item meshes
        /// </summary>
        protected override void DoRender()
        {
            long startTime = timer.CurrentTotalTime;
            foreach (Mesh m in meshes)
                m.Render(this);
            NLog.LogManager.GetLogger(ToString()).Debug(ToString() + " Rendered in " + (timer.CurrentTotalTime - startTime) + " ms");
        }

        /// <summary>
        /// \internal Updates the item motion and audio
        /// </summary>
        protected override void DoUpdate()
        {
            long startTime = timer.CurrentTotalTime;
            base.DoUpdate();
            
            foreach (Audio a in audios)
                a.Update(this);
            NLog.LogManager.GetLogger(ToString()).Debug(ToString() + " Updated in " + (timer.CurrentTotalTime - startTime) + " ms");
        }

        /// <summary>
        /// \internal Clears every mesh and audio list
        /// </summary>
        public override void Dispose()
        {
            meshes.Clear();
            meshes = null;
            foreach (Audio a in audios)
                a.Stop();
            audios.Clear();
            audios = null;
            timer = null;
            base.Dispose();
        }
        
    }
}
